/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rosic.mapCanvas;

import com.sun.lwuit.Command;
import com.sun.lwuit.Component;
import com.sun.lwuit.Display;
import com.sun.lwuit.Font;
import com.sun.lwuit.Graphics;
import com.sun.lwuit.Image;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import java.util.Vector;
import rosic.GoogleMaps.Marcador;
import rosic.GoogleMaps.RutaMapa;
import rosic.forms.MidletPrincipal;

/**
 *
 * @author David
 */
public class MapCanvas extends Component {

    /**
     * clase principal de la aplicación
     */
    private MidletPrincipal midletPrincipal;
    /**
     * Velocidad a la que se desplaza el cursor
     */
    private int tampaso = 4;
    /**
     * Estas son las coordenadas donde se ubica el cursor.
     */
    private int xCursor, yCursor;
    /**
     * Imagen que corresponde al mapa.
     */
    private MapImage mapa;
    /**
     * coordenada x del centro del circulo en el que se muestra la ubicacion del usuario
     */
    private int coordXCentro;
    /**
     * coordenada y del centro del circulo en el que se muestra la ubicacion del usuario
     */
    private int coordYCentro;
    /**
     * vector con los marcadores a pintar
     */
    private Vector marcadores;
    /**
     * latitud del usuario,
     */
    private double latitud;
    /**
     * longitud del usuario
     */
    private double longitud;
    /**
     * ruta a para pintar en el mapa
     */
    private RutaMapa ruta;
    //------------------------------------------------------------------
    // Colores
    //------------------------------------------------------------------
    private final static String ROBO_MANO_BLANCA = "robo con arma blanca";
    private final static String ROBO_ARMA_FUEGO = "robo con arma de fuego";
    private final static String CHALEQUEO = "chalequeo";
    private final static String VIOLACION = "violacion";
    private final static String SECUESTRO = "secuestro";
    private final static int COLOR_NEGRO = 0x000000;
    private final static int COLOR_NARANJA = 0xFF8000;
    private final static int COLOR_VERDE = 0x04B404;
    private final static int COLOR_AZUL = 0x0000FF;
    private final static int COLOR_MORADO = 0x8A0886;
    //------------------------------------------------------------------
    //conversion de coordenadas
    //-------------------------------------------------------------------
    private double MLongitud = 22000;
    private double BLongitud = 1629685.06;
    private double MLatidud = -24000;
    private double BLatitud = 110686.96;
    private double MDescacheY = -24000;
    private double MDescacheX = 21999.999999895;
    private final static double LATITUD_REFERENCIA = 4.60154;
    private final static double LONGITUD_REFERENCIA = -74.06523;
    /**
     * descache en en x para calcular la coortendada x del marcador
     */
    private int descahceX = 0;
    /**
     * descache en y para clacular la coordenada y del marcador
     */
    private int descacheY = 0;

    /**
     * constructor de la clase
     * @param principal
     * @param mapa Image con el mapa a mostrar
     */
    public MapCanvas(MidletPrincipal principal, Image imagenMapa, int anchoMapa, int altoMapa, double latitud, double longitud, int width, int height) {


        midletPrincipal = principal;
        mapa = new MapImage(imagenMapa, anchoMapa, altoMapa);

        this.latitud = latitud;
        this.longitud = longitud;

        descacheY = (int) ((LATITUD_REFERENCIA - latitud) * MDescacheY);
        descahceX = (int) ((LONGITUD_REFERENCIA - longitud) * MDescacheX);
        // descahceX=67;

        // mapa.setxMap(getWidth() / 2 + mapa.getWidth() / 2);
        System.out.println("anchoMapa");
        System.out.println(mapa.getWidth());
        // mapa.setxMap(getWidth() / 2 - mapa.getWidth() / 2);
        // mapa.setyMap(getHeight() / 2 - mapa.getHeight() / 2);

        mapa.setxMap(width / 2 - mapa.getWidth() / 2);

        mapa.setyMap(height / 2 - mapa.getHeight() / 2);

        System.out.println("fin constructor");

        System.out.println(mapa.getWidth());
        System.out.println(mapa.getHeight());
        repaint();

        

        //Inicializa los botones.
       /* comandoAtras = new Command("Volver", Command.SCREEN, 1);
        addCommand(comandoAtras);
        setCommandListener(this);*/

    }

    public void paint(Graphics graphics) {
        //Dibuja el fondo blaco de la pantalla.
        graphics.setColor(0xFFFFFF);
        graphics.fillRect(0, 0, getWidth(), getHeight());

        // System.out.println("llama a paint");
        mapa.paint(graphics);

        pintarUbicacionUsuario(graphics);

        pintarMarcadores(graphics);

        pintarRuta(graphics);



    }
    /**
     * pinta la ruta que se guarda en la instancia de esta clase
     * la ruta debe tener mas de un punto para que se visualice correctamente
     * @param gr
     */
    private void pintarRuta(Graphics gr){
            int xMap = mapa.getxMap();
            int yMap = mapa.getyMap();
            
        if(getRuta()!=null){
            Vector marcadores = getRuta().getPuntos();

            Marcador marcador1 = (Marcador) marcadores.elementAt(0);
            int x1=convertirCoordX(marcador1.getLongitud());
            int y1=convertirCoordY(marcador1.getLatitud());

            System.out.println("Latitud1(y): " + marcador1.getLatitud());
             System.out.println("Y: " + y1);

            System.out.println("Longitud1(x): " + marcador1.getLongitud());
            System.out.println("X: " + x1);

            
            for(int i=1;i<marcadores.size();i++){
                Marcador marcActual = (Marcador) marcadores.elementAt(i);

                int x2=convertirCoordX(marcActual.getLongitud());
                int y2=convertirCoordY(marcActual.getLatitud());

                

                gr.drawLine(xMap+x1, yMap+y1, xMap+x2, yMap+y2);

                x1=x2;
                y1=y2;
                
            }

        }

    }
    /**
     * pinta la ubicación del usuario, lo pinta en la mitad de la imagen
     * @param g Graphics donde se va a pintar
     */
    private void pintarUbicacionUsuario(Graphics gr) {

        int xMap = mapa.getxMap();
        int yMap = mapa.getyMap();

        int x = mapa.getWidth() / 2;
        int y = mapa.getHeight() / 2;

        coordXCentro = x;
        coordYCentro = y;

        // System.out.println("Coord x en Mapa: " + coordXCentro);

        //   System.out.println("Coord y en Mapa: " + coordYCentro);




        String texto = "Usted está aqui";

        int tamCirculo = 4;

        gr.setColor(0xFF0000);
        gr.fillArc(xMap + x - tamCirculo / 2, yMap + y - tamCirculo / 2, tamCirculo, tamCirculo, 0, 360);
        gr.drawArc(xMap + x - tamCirculo, yMap + y - tamCirculo, tamCirculo * 2, tamCirculo * 2, 0, 360);
        gr.drawArc(xMap + x - tamCirculo * 2, yMap + y - tamCirculo * 2, tamCirculo * 4, tamCirculo * 4, 0, 360);



        gr.setColor(0xFFFFFF);

        gr.fillTriangle(xMap + x, yMap + y, xMap + x + 7, yMap + y, xMap + x + 7, yMap + y + 5);

        gr.fillRoundRect(xMap + x + 7, yMap + y - 2, texto.length() * 7 + 4, 20, 8, 8);

        gr.setColor(0x000000);
        gr.setFont(Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
        gr.drawString(texto, xMap + x + 11, yMap + y);
    }

    private void pintarMarcador(Graphics gr, double latitud, double longitud, String mensaje) {

        int xMap = mapa.getxMap();
        int yMap = mapa.getyMap();

        int x = convertirCoordX(longitud);
        int y = convertirCoordY(latitud);

        //System.out.println("Coord x en Mapa punto2: " + x);

        // System.out.println("Coord y en Mapa punto 2: " + y);


        int tamCirculo = 4;

        boolean pintarTexto=true;

        String texto = mensaje;
        if (texto != null) {

            if (texto.equalsIgnoreCase(ROBO_ARMA_FUEGO)) {
                pintarTexto=false;
                gr.setColor(COLOR_AZUL);
            } else if (texto.equalsIgnoreCase(ROBO_MANO_BLANCA)) {
                pintarTexto=false;
                gr.setColor(COLOR_MORADO);
            } else if (texto.equalsIgnoreCase(CHALEQUEO)) {
                pintarTexto=false;
                gr.setColor(COLOR_NARANJA);
            } else if (texto.equalsIgnoreCase(SECUESTRO)) {
                pintarTexto=false;
                gr.setColor(COLOR_VERDE);
            } else if (texto.equalsIgnoreCase(VIOLACION)) {
                pintarTexto=false;
                gr.setColor(COLOR_NEGRO);
            } else {
                gr.setColor(0x0404B4);
            }

        } else {
            gr.setColor(0x0404B4);
        }



        gr.fillArc(xMap + x - tamCirculo / 2, yMap + y - tamCirculo / 2, tamCirculo, tamCirculo, 0, 360);
        gr.drawArc(xMap + x - tamCirculo, yMap + y - tamCirculo, tamCirculo * 2, tamCirculo * 2, 0, 360);
        gr.drawArc(xMap + x - tamCirculo * 2, yMap + y - tamCirculo * 2, tamCirculo * 4, tamCirculo * 4, 0, 360);



        if (texto != null) {
            if (!texto.equals("")&&pintarTexto) {

                gr.setColor(0xA9A9F5);
                gr.fillTriangle(xMap + x, yMap + y, xMap + x + 7, yMap + y, xMap + x + 7, yMap + y + 5);
                gr.fillRoundRect(xMap + x + 7, yMap + y - 2, texto.length() * 7 + 4, 20, 8, 8);

                gr.setColor(0x0101DF);
                gr.setFont(Font.createSystemFont(Font.FACE_PROPORTIONAL, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
                gr.drawString(texto, xMap + x + 11, yMap + y);

            }
        }



    }

    /**
     * Escucha cuando el usuario oprime una tecla.
     * @param key Tecla que se oprimió.
     */
    public void keyPressed(int key) {

        int keyConvertida = Display.getInstance().getGameAction(key);
        switch (keyConvertida) {
            case Display.GAME_UP:
                //De contrario, mueve el mapa hasta que llegue al borde superior de la pantalla.
                if (mapa.getyMap() + tampaso <= 0) {
                    mapa.setyMap(mapa.getyMap() + tampaso);
                }
                break;
            case Display.GAME_DOWN:

                if (mapa.getyMap() - tampaso + mapa.getHeight() >= getHeight()) {
                    mapa.setyMap(mapa.getyMap() - tampaso);
                }

                break;
            case Display.GAME_LEFT:
                //Se oprimió la tecla izquierda (Lo que sigue es similar en todas las direcciones)
                if (mapa.getxMap() + tampaso <= 0) {
                    mapa.setxMap(mapa.getxMap() + tampaso);
                }

                break;
            case Display.GAME_RIGHT:
                //Se oprimió la tecla derecha (Lo que sigue es similar en todas las direcciones)

                if (mapa.getxMap() - tampaso + mapa.getWidth() >= getWidth()) {
                    mapa.setxMap(mapa.getxMap() - tampaso);

                }
                break;

        }
        repaint();
    }

    /**
     * Escucha cuando el usuario mantiene oprimida una tecla.
     * @param key Tecla que se estaba oprimiendo
     */
    public void keyRepeated(int key) {

        //Acelera el movimiento.
        if (tampaso < 40) {
            tampaso += 2;
        }
        int keyConvertida = Display.getInstance().getGameAction(key);
        switch (keyConvertida) {
            case Display.GAME_UP:
                //De contrario, mueve el mapa hasta que llegue al borde superior de la pantalla.
                if (mapa.getyMap() + tampaso <= 0) {
                    mapa.setyMap(mapa.getyMap() + tampaso);
                }
                break;
            case Display.GAME_DOWN:

                if (mapa.getyMap() - tampaso + mapa.getHeight() >= getHeight()) {
                    mapa.setyMap(mapa.getyMap() - tampaso);
                }

                break;
            case Display.GAME_LEFT:
                //Se oprimió la tecla izquierda (Lo que sigue es similar en todas las direcciones)
                if (mapa.getxMap() + tampaso <= 0) {
                    mapa.setxMap(mapa.getxMap() + tampaso);
                }

                break;
            case Display.GAME_RIGHT:
                //Se oprimió la tecla derecha (Lo que sigue es similar en todas las direcciones)

                if (mapa.getxMap() - tampaso + mapa.getWidth() >= getWidth()) {
                    mapa.setxMap(mapa.getxMap() - tampaso);

                }
                break;

        }
        repaint();
    }

    /**
     * davuelve la coordenada x correspondiente a la longitud de google maps ingresada
     * @param longitud
     * @return
     */
    private int convertirCoordX(double longitud) {
        int resp = (int) ((int) (MLongitud * longitud) + BLongitud);
        return resp + descahceX;
    }

    /**
     * davuelve la coordenada y correspondiente a la latitud de google maps ingresada
     * @param latitud
     * @return
     */
    private int convertirCoordY(double latitud) {
        int resp = (int) ((int) (MLatidud * latitud) + BLatitud);
        return resp + descacheY;
    }

    /**
     * Escucha cuando el usuario suelta una tecla.
     * @param key Tecla que se estaba oprimiendo
     */
    public void keyReleased(int key) {
        try {
            //Reestablece el tamaño del paso
            tampaso = 4;
            repaint();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @return the Marcadores
     */
    public Vector getMarcadores() {
        return marcadores;
    }

    /**
     * @param Marcadores the Marcadores to set
     */
    public void setMarcadores(Vector Marcadores) {
        this.marcadores = Marcadores;
    }

    private void pintarMarcadores(Graphics graphics) {
        if (marcadores != null) {

            for (int i = 0; i < marcadores.size(); i++) {
                Marcador marcActual = (Marcador) marcadores.elementAt(i);
                pintarMarcador(graphics, marcActual.getLatitud(), marcActual.getLongitud(), marcActual.getMensaje());
            }

        }

    }

    /**
     * @return the ruta
     */
    public RutaMapa getRuta() {
        return ruta;
    }

    /**
     * @param ruta the ruta to set
     */
    public void setRuta(RutaMapa ruta) {
        this.ruta = ruta;
    }
}

